package com.ugoodtech.mdcc.client.service.impl;

import com.ugoodtech.mdcc.client.dto.PerformancePlanData;
import com.ugoodtech.mdcc.client.dto.PerformancePlanData.MonthData;
import com.ugoodtech.mdcc.client.dto.PerformancePlanVO;
import com.ugoodtech.mdcc.core.domain.PerformanceReportDetail;
import com.ugoodtech.mdcc.client.common.BizConstants.PerformancePlan;
import com.ugoodtech.mdcc.client.exception.BizException;
import com.ugoodtech.mdcc.client.exception.EnumBizError;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class PerformancePlanCalculator {

	@Autowired
	private PerformancePlanRecordsFilter filter;

	public PerformancePlanVO convertValuesList(
			List<PerformanceReportDetail> performanceReportDetailDOs, Integer year) {
		return fillInData(performanceReportDetailDOs, year);
	}

	/**
	 * 填充业绩报告相关信息，如销售额，达成率等
	 */
	public PerformancePlanVO fillInData(List<PerformanceReportDetail> performanceReportDetailDOs,
			Integer year) {
		Map<Integer, List<PerformanceReportDetail>> dataMap = extractMonthData(
				performanceReportDetailDOs);
		// 根据各种类型归类数据
		PerformancePlanVO performancePlanVO = categorizeData(performanceReportDetailDOs);
		// 设置当前业绩报告年份
		performancePlanVO.setYear(year);
		calculateAnnualAndSeasonStatistic(performancePlanVO);
		calculateSaleSumData(performancePlanVO);
		calculateCompletionRate(performancePlanVO);
		calculateMonthData(performancePlanVO);
		setItemString(performancePlanVO);
		return performancePlanVO;
	}

	/**
	 * 填充业绩报告相关信息，如销售额，达成率等
	 */
	public PerformancePlanVO fillInDataSimply(
			List<PerformanceReportDetail> performanceReportDetailDOs,
			Integer year) {
		// 根据各种类型归类数据
		PerformancePlanVO performancePlanVO = categorizeData(performanceReportDetailDOs);
		// 设置当前业绩报告年份
		performancePlanVO.setYear(year);
		calculateAnnualAndSeasonStatistic(performancePlanVO);
		calculateSaleSumData(performancePlanVO);
		calculateMonthData(performancePlanVO);
		setItemString(performancePlanVO);
		return performancePlanVO;
	}

	private void setItemString(PerformancePlanVO planVO) {
		for (PerformancePlanData performancePlanData : planVO.getData()) {
			performancePlanData
					.setProjectStr(PerformancePlan.getProjectString(performancePlanData.getProject()));
			performancePlanData
					.setStatusStr(PerformancePlan.getOperationType(performancePlanData.getStatus()));
			performancePlanData.setBrandOrientationStr(
					PerformancePlan.getBrand(performancePlanData.getBrandOrientation()));
		}
	}


	/**
	 * 填充月度季度和年度数据
	 */
	private void calculateMonthData(PerformancePlanVO performancePlanVO) {
		for (PerformancePlanData planData : performancePlanVO.getData()) {
			// 在除了集采和非集采的数据中, 如果月度数据没有时添加月度数据
			if (CollectionUtils.isEmpty(planData.getMonthModificationData())) {
				// 从数据集合中提取月度数据
				List<BigDecimal> collectionData = planData.getCollectionData();
				List<PerformancePlanData.MonthData> monthDataModificationList = new ArrayList<>(12);
				List<BigDecimal> monthDataList = new ArrayList<>(12);
				for (int i = 0; i < 12; i++) {
					monthDataModificationList.add(new PerformancePlanData.MonthData(null, collectionData.get(i), null));
					monthDataList.add(collectionData.get(i));
				}
				planData.setMonthModificationData(monthDataModificationList);
				planData.setMonthData(monthDataList);
				// 添加年度数据和季度度数据
				List<BigDecimal> seasonDataList = new ArrayList<>(4);
				for (int i = 13; i < 17; i++) {
					seasonDataList.add(collectionData.get(i));
				}
				planData.setSeasonStatisticsData(seasonDataList);
				planData.setAnnualStatisticsData(collectionData.get(12));
			}
		}
	}

	public List<PerformancePlanData> fillInData(
			List<PerformanceReportDetail> performanceReportDetailDOs) {
		return categorizeData(performanceReportDetailDOs).getData();
	}

	/**
	 * 归类数据
	 */
	private PerformancePlanVO categorizeData(
			List<PerformanceReportDetail> performanceReportDetailDOs) {
		PerformancePlanVO performancePlanVO = new PerformancePlanVO();
		for (PerformanceReportDetail p : performanceReportDetailDOs) {
			// 获取同样类型的之前计算过的数据
			PerformancePlanData performancePlanData = getSpecificData(performancePlanVO,
					p.getYear(), p.getStatus(), p.getBrandType(), p.getCustomerType(), p.getVersion());
			// 未找到对应类型数据则添加, 否则在原类型数据下面添加月度数据
			if (Objects.isNull(performancePlanData)) {
				PerformancePlanData planData = new PerformancePlanData();
				planData.setBrandOrientation(p.getBrandType());
				planData.setStatus(p.getStatus());
				planData.setYear(p.getYear());
				planData.setVersion(p.getVersion());
				planData.setProject(p.getCustomerType());
				planData.getMonthMap().put(p.getMonth(), p.getSales());
				MonthData monthData = new MonthData();
				BeanUtils.copyProperties(p, monthData);
				planData.getMonthModificationDataMap().put(p.getMonth(), monthData);
				performancePlanVO.getData().add(planData);
			} else {
				MonthData monthData = new MonthData();
				BeanUtils.copyProperties(p, monthData);
				performancePlanData.getMonthModificationDataMap().put(p.getMonth(), monthData);
				performancePlanData.getMonthMap().put(p.getMonth(), p.getSales());
			}
		}
		Map<Integer, BigDecimal> monthMap = null;
		Map<Integer, MonthData> monthModificationDataMap = null;
		BigDecimal value = null;
		MonthData monthData = null;
		for (PerformancePlanData p : performancePlanVO.getData()) {
			monthMap = p.getMonthMap();
			monthModificationDataMap = p.getMonthModificationDataMap();
			for (int i = 1; i <= 12; i++) {
				value = monthMap.get(i);
				monthData = monthModificationDataMap.get(i);
				if (null == value) {
					p.getMonthData().add(null);
					p.getMonthModificationData().add(null);
				} else {
					p.getMonthModificationData().add(monthData);
					p.getMonthData().add(value);
				}
			}
		}
		return performancePlanVO;
	}

	/**
	 * 计算集采非集采的月度数据和年度数据
	 */
	public void calculateAnnualAndSeasonStatistic(PerformancePlanVO performancePlanVO) {
		for (PerformancePlanData performancePlanData : performancePlanVO.getData()) {
			List<BigDecimal> monthData = performancePlanData.getMonthData();
			BigDecimal seasonData = null;
			BigDecimal annualData = BigDecimal.ZERO;
			BigDecimal singleMonthData = null;
			boolean isSeasonAdded = false;
			boolean isYearAdded = false;
			for (int i = 0; i < 12; i++) {
				singleMonthData = monthData.get(i);
				if ((i + 1) % 3 == 1) {
					isSeasonAdded = false;
					seasonData = null;
				}
				if (!Objects.isNull(singleMonthData)) {
					if (Objects.isNull(seasonData)) {
						seasonData = singleMonthData;
					} else {
						seasonData = seasonData.add(singleMonthData);
					}
					if (!Objects.isNull(seasonData) && !isSeasonAdded) {
						isSeasonAdded = true;
					}
				}
				if ((i + 1) % 3 == 0) {
					performancePlanData.getSeasonStatisticsData().add(seasonData);
				}
				if (!Objects.isNull(singleMonthData)) {
					annualData = annualData.add(singleMonthData);
					if (annualData.compareTo(BigDecimal.ZERO) != 0 && !isYearAdded) {
						isYearAdded = true;
					}
				}
			}
			performancePlanData.setAnnualStatisticsData(annualData);
			performancePlanData.getCollectionData().addAll(performancePlanData.getMonthData());
			performancePlanData.getCollectionData().add(annualData);
			performancePlanData.getCollectionData().addAll(performancePlanData.getSeasonStatisticsData());
		}
	}

	/**
	 * 计算销售额合计
	 */
	public void calculateSaleSumData(PerformancePlanVO performancePlanVO) {
		List<PerformancePlanData> performancePlanDataList = new ArrayList<>();
		performancePlanDataList.addAll(performancePlanVO.getData());
		// 对每一类数据都有销售额合计, 对每一类数据都要计算
		for (PerformancePlanData performancePlanData : performancePlanDataList) {
			// 判断是否有销售额合计的内容
			if (null == getSpecificData(performancePlanVO, performancePlanData.getYear(),
					performancePlanData.getStatus(), performancePlanData.getBrandOrientation(),
					PerformancePlan.PROJECT_SALE_AMOUNT, performancePlanData.getVersion())) {
				// 获取另一种类型的数据
				PerformancePlanData another = getAnotherCollectionTypeData(performancePlanVO,
						performancePlanData);
				if (log.isTraceEnabled()) {
					log.trace("计算销售额合计, [{}], [{}].", performancePlanData, another);
				}
				if (Objects.isNull(another)) {
					throw new BizException(EnumBizError.OPERATION_FAIL.setErrMsg("数据错误"));
				}
				// 添加新的数据, 表示是销售额合计的数据
				PerformancePlanData newData = new PerformancePlanData();
				newData.setProject(PerformancePlan.PROJECT_SALE_AMOUNT);
				newData.setYear(performancePlanData.getYear());
				newData.setVersion(performancePlanData.getVersion());
				newData.setStatus(performancePlanData.getStatus());
				newData.setBrandOrientation(performancePlanData.getBrandOrientation());
				newData.setCollectionData(
						sum(performancePlanData.getCollectionData(), another.getCollectionData()));
				performancePlanVO.getData().add(newData);
			}
		}
	}

	/**
	 * 计算预测和实际的达成率
	 */
	private void calculateCompletionRate(PerformancePlanVO planVO) {
		calculateForecastCompletionRate(planVO);
		calculateRealisticData(planVO);
	}

	/**
	 * 计算实际的达成差额和与往年相比数据
	 */
	private void calculateRealisticData(PerformancePlanVO planVO) {
		// 先计算达成差额, 再计算达成率
		List<PerformancePlanData> performancePlanDataList = new ArrayList<>(planVO.getData());
		Integer thisYear = planVO.getYear();
		for (PerformancePlanData performancePlanData : performancePlanDataList) {
			// 如果存在实际销售额的今年数据, 则计算达成差额
			if (Objects.equals(performancePlanData.getStatus(), PerformancePlan.OPERATION_TYPE_REALISTIC)
					&& Objects
					.equals(performancePlanData.getProject(), PerformancePlan.PROJECT_SALE_AMOUNT)
					&& Objects.equals(performancePlanData.getYear(), planVO.getYear())) {
				boolean isDataLatest = checkIfThisDataIsLatest(planVO, performancePlanData.getYear(),
						performancePlanData.getStatus(), performancePlanData.getBrandOrientation(),
						performancePlanData.getProject(), performancePlanData.getVersion());
				// 获取今年的计划销售额数据
				PerformancePlanData data = getSpecificData(planVO, performancePlanData.getYear(),
						PerformancePlan.OPERATION_TYPE_PLAN, performancePlanData.getBrandOrientation(),
						PerformancePlan.PROJECT_SALE_AMOUNT, isDataLatest);
				if (Objects.isNull(data)) {
					throw new BizException(EnumBizError.OPERATION_FAIL.setErrMsg("数据有误, 计算达成率失败"));
				}
				// 添加新的数据, 表示是计划销售额的数据
				PerformancePlanData newData = new PerformancePlanData();
				newData.setProject(PerformancePlan.PROJECT_RATE);
				newData.setYear(performancePlanData.getYear());
				newData.setVersion(performancePlanData.getVersion());
				newData.setStatus(performancePlanData.getStatus());
				newData.setBrandOrientation(performancePlanData.getBrandOrientation());
				newData.setCollectionData(
						multiply(divide(performancePlanData.getCollectionData(), data.getCollectionData()),
								BigDecimal.valueOf(100)));
				planVO.getData().add(newData);
				// 添加新的数据, 表示是达成差额的数据
				newData = new PerformancePlanData();
				newData.setProject(PerformancePlan.PROJECT_BALANCE);
				newData.setYear(performancePlanData.getYear());
				newData.setStatus(performancePlanData.getStatus());
				newData.setVersion(performancePlanData.getVersion());
				newData.setBrandOrientation(performancePlanData.getBrandOrientation());
				newData.setCollectionData(
						subtract(performancePlanData.getCollectionData(), data.getCollectionData()));
				planVO.getData().add(newData);
				data = getSpecificData(planVO, thisYear - 1,
						PerformancePlan.OPERATION_TYPE_REALISTIC, performancePlanData.getBrandOrientation(),
						PerformancePlan.PROJECT_SALE_AMOUNT, isDataLatest);
				if (!Objects.isNull(data)) {
					// 添加新的数据, 表示是与往年相比的的数据
					newData = new PerformancePlanData();
					newData.setProject(PerformancePlan.PROJECT_COMPARISION);
					newData.setYear(performancePlanData.getYear());
					newData.setVersion(performancePlanData.getVersion());
					newData.setStatus(performancePlanData.getStatus());
					newData.setBrandOrientation(performancePlanData.getBrandOrientation());
					newData.setCollectionData(
							subtract(performancePlanData.getCollectionData(), data.getCollectionData()));
					planVO.getData().add(newData);
				}
			}
		}
	}


	private void calculateForecastCompletionRate(PerformancePlanVO performancePlanVO) {
		List<PerformancePlanData> performancePlanDataList = new ArrayList<>();
		performancePlanDataList.addAll(performancePlanVO.getData());
		for (PerformancePlanData performancePlanData : performancePlanDataList) {
			// 如果是预测且是今年的销售额数据, 则计算达成率
			if (Objects.equals(performancePlanData.getStatus(), PerformancePlan.OPERATION_TYPE_FORECAST)
					&& Objects
					.equals(performancePlanData.getProject(), PerformancePlan.PROJECT_SALE_AMOUNT)
					&& Objects.equals(performancePlanData.getYear(), performancePlanVO.getYear())) {
				// 获取计划销售额数据
				PerformancePlanData data = getSpecificData(performancePlanVO, performancePlanData.getYear(),
						PerformancePlan.OPERATION_TYPE_PLAN, performancePlanData.getBrandOrientation(),
						PerformancePlan.PROJECT_SALE_AMOUNT,
						checkIfThisDataIsLatest(performancePlanVO, performancePlanData.getYear(),
								performancePlanData.getStatus(), performancePlanData.getBrandOrientation(),
								performancePlanData.getProject(), performancePlanData.getVersion()));
				if (Objects.isNull(data)) {
					throw new BizException(EnumBizError.OPERATION_FAIL.setErrMsg("数据有误, 计算达成率失败"));
				}
				// 添加新的数据, 表示是达成率的数据
				PerformancePlanData newData = new PerformancePlanData();
				newData.setProject(PerformancePlan.PROJECT_RATE);
				newData.setYear(performancePlanData.getYear());
				newData.setVersion(performancePlanData.getVersion());
				newData.setStatus(performancePlanData.getStatus());
				newData.setBrandOrientation(performancePlanData.getBrandOrientation());
				newData.setCollectionData(
						multiply(divide(performancePlanData.getCollectionData(), data.getCollectionData()),
								BigDecimal.valueOf(100)));
				performancePlanVO.getData().add(newData);
			}
		}
	}

	public PerformancePlanVO checkSeasonAnnualModification(PerformancePlanVO planVO) {
		List<PerformancePlanData> performancePlanDataList = new ArrayList<>();
		performancePlanDataList.addAll(planVO.getData());
		for (PerformancePlanData performancePlanData : performancePlanDataList) {
			// 查看该数据是否需要标注修改信息
//			if (isDataNeedSetModificationSign(performancePlanData)) {
			// 计算这个版本和上个版本的数据是否有变化
			PerformancePlanData lastVersionData = getSpecificData(planVO, performancePlanData.getYear(),
					performancePlanData.getStatus(), performancePlanData.getBrandOrientation(),
					performancePlanData.getProject(), performancePlanData.getVersion() - 1);
			// 如果当前编辑的数据和找到的数据一致, 都是老版本的同一类型的数据, 则跳过
			if (lastVersionData != null) {
				calculateModificationData(performancePlanData, lastVersionData);
			} else {
				// 找不到上个版本数据情况下, 计算这个版本的数据修改情况
				List<BigDecimal> thisYearSeasonData = performancePlanData.getSeasonStatisticsData();
				BigDecimal thisYearAnnualData = performancePlanData.getAnnualStatisticsData();
				List<MonthData> seasonModificationData = new ArrayList<>(4);
				for (int i = 0; i < 4; i++) {
					seasonModificationData.add(new MonthData(null, thisYearSeasonData.get(i), 0));
				}
				performancePlanData.setSeasonModificationData(seasonModificationData);
				performancePlanData.setYearModificationData(new MonthData(null, thisYearAnnualData, 0));
			}
//			}
		}
		planVO.setData(performancePlanDataList);
		return planVO;
	}

	private void calculateModificationData(PerformancePlanData thisYearData,
			PerformancePlanData lastYearData) {
		// 计算这个版本的月度数据相较上个版本是否有变化
		List<BigDecimal> lastYearMonthData = lastYearData.getMonthData();
		List<BigDecimal> thisYearMonthData = thisYearData.getMonthData();
		if (lastYearMonthData == null || lastYearMonthData.size() != 12
				|| thisYearMonthData == null || thisYearMonthData.size() != 12) {
			throw new BizException(EnumBizError.OPERATION_FAIL.setErrMsg("月度数据错误"));
		}
		List<MonthData> monthModificationData = new ArrayList<>(4);
		for (int i = 0; i < 12; i++) {
			// 比较今年这个季度和去年这个季度的数据, 如果不一样则表示修改过
			if (lastYearMonthData.get(i) == null || thisYearMonthData.get(i) == null) {
				monthModificationData.add(new MonthData(null, null, 0));
			} else if (lastYearMonthData.get(i).compareTo(thisYearMonthData.get(i)) != 0) {
				monthModificationData.add(new MonthData(null, thisYearMonthData.get(i), 1));
			} else {
				monthModificationData.add(new MonthData(null, thisYearMonthData.get(i), 0));
			}
		}
		thisYearData.setMonthModificationData(monthModificationData);
		// 计算这个版本的季度和年度数据相较上个版本是否有变化
		List<BigDecimal> lastYearSeasonData = lastYearData.getSeasonStatisticsData();
		BigDecimal lastYearAnnualData = lastYearData.getAnnualStatisticsData();
		List<BigDecimal> thisYearSeasonData = thisYearData.getSeasonStatisticsData();
		BigDecimal thisYearAnnualData = thisYearData.getAnnualStatisticsData();
		if (lastYearSeasonData == null || lastYearSeasonData.size() != 4
				|| thisYearSeasonData == null || thisYearSeasonData.size() != 4) {
			throw new BizException(EnumBizError.OPERATION_FAIL.setErrMsg("季度数据错误"));
		}
		List<MonthData> seasonModificationData = new ArrayList<>(4);
		for (int i = 0; i < 4; i++) {
			// 比较今年这个季度和去年这个季度的数据, 如果不一样则表示修改过
			if (lastYearSeasonData.get(i) == null || thisYearSeasonData.get(i) == null) {
				seasonModificationData.add(new MonthData(null, null, 0));
			} else if (lastYearSeasonData.get(i).compareTo(thisYearSeasonData.get(i)) != 0) {
				seasonModificationData.add(new MonthData(null, thisYearSeasonData.get(i), 1));
			} else {
				seasonModificationData.add(new MonthData(null, thisYearSeasonData.get(i), 0));
			}
		}
		thisYearData.setSeasonModificationData(seasonModificationData);
		// 计算年度数据变化
		if (thisYearAnnualData == null || lastYearAnnualData == null) {
			monthModificationData.add(new MonthData(null, null, 0));
		} else if (thisYearAnnualData.compareTo(lastYearAnnualData) != 0) {
			thisYearData.setYearModificationData(new MonthData(null, thisYearAnnualData, 1));
		} else {
			thisYearData.setYearModificationData(new MonthData(null, thisYearAnnualData, 0));
		}
	}

	private Boolean isDataNeedSetModificationSign(PerformancePlanData performancePlanData) {
		return (Objects.equals(performancePlanData.getProject(), PerformancePlan.PROJECT_COLLECTION)
				|| Objects.equals(performancePlanData.getProject(), PerformancePlan.PROJECT_NOT_COLLECTION)
				|| Objects.equals(performancePlanData.getProject(), PerformancePlan.PROJECT_SALE_AMOUNT))
				&& Objects.equals(performancePlanData.getStatus(), PerformancePlan.OPERATION_TYPE_PLAN);
	}

	private List<BigDecimal> sum(List<BigDecimal> one, List<BigDecimal> two) {
		if (one == null || two == null || one.size() != two.size()) {
			throw new BizException(EnumBizError.OPERATION_FAIL.setErrMsg("数据错误"));
		}
		List<BigDecimal> sum = new ArrayList<>(one.size());
		BigDecimal first = null, second = null;
		for (int i = 0, j = one.size(); i < j; i++) {
			first = one.get(i);
			second = two.get(i);
			if (Objects.isNull(first)) {
				if (Objects.isNull(second)) {
					sum.add(null);
				} else {
					sum.add(second);
				}
			} else {
				if (Objects.isNull(second)) {
					sum.add(first);
				} else {
					sum.add(first.add(second));
				}
			}
		}
		return sum;
	}

	private List<BigDecimal> divide(List<BigDecimal> one, List<BigDecimal> two) {
		if (one == null || two == null || one.size() != two.size()) {
			throw new BizException(EnumBizError.OPERATION_FAIL.setErrMsg("计算错误"));
		}
		if (log.isDebugEnabled()) {
			log.debug("计算两者相除, [{}], [{}].", one, two);
		}
		List<BigDecimal> divide = new ArrayList<>(one.size());
		BigDecimal first = null, second = null;
		for (int i = 0, j = one.size(); i < j; i++) {
			first = one.get(i);
			second = two.get(i);
			if (Objects.isNull(first) || Objects.isNull(second) || second.intValue()==0) {
				divide.add(null);
			} else {
				divide.add(first.divide(second, 2, RoundingMode.HALF_UP));
			}
		}
		return divide;
	}

	private List<BigDecimal> multiply(List<BigDecimal> one, BigDecimal multiply) {
		if (one == null || multiply == null) {
			throw new BizException(EnumBizError.OPERATION_FAIL.setErrMsg("计算错误"));
		}
		if (log.isDebugEnabled()) {
			log.debug("放大倍数, [{}], [{}].", one, multiply);
		}
		List<BigDecimal> multiplyResult = new ArrayList<>(one.size());
		BigDecimal first = null;
		for (int i = 0, j = one.size(); i < j; i++) {
			first = one.get(i);
			if (Objects.isNull(first)) {
				multiplyResult.add(null);
			} else {
				multiplyResult.add(first.multiply(multiply));
			}
		}
		return multiplyResult;
	}

	private List<BigDecimal> subtract(List<BigDecimal> one, List<BigDecimal> two) {
		if (one == null || two == null || one.size() != two.size()) {
			throw new BizException(EnumBizError.OPERATION_FAIL.setErrMsg("计算错误"));
		}
		if (log.isDebugEnabled()) {
			log.debug("计算达成差额, [{}], [{}].", one, two);
		}
		List<BigDecimal> divide = new ArrayList<>(one.size());
		BigDecimal first = null, second = null, minusOne = BigDecimal.valueOf(-1);
		for (int i = 0, j = one.size(); i < j; i++) {
			first = one.get(i);
			second = two.get(i);
			if (Objects.isNull(first) || Objects.isNull(second)) {
				divide.add(null);
			} else {
				divide.add(first.subtract(second));
			}
		}
		return divide;
	}

	/**
	 * 获取另一种客户类型(集采, 非集采数据)
	 */
	private PerformancePlanData getAnotherCollectionTypeData(PerformancePlanVO performancePlanVO,
			PerformancePlanData performancePlanData) {
		switch (performancePlanData.getProject()) {
			case PerformancePlan
					.PROJECT_COLLECTION:
				return getSpecificData(performancePlanVO, performancePlanData.getYear(),
						performancePlanData.getStatus(), performancePlanData.getBrandOrientation(),
						PerformancePlan.PROJECT_NOT_COLLECTION, performancePlanData.getVersion());
			case PerformancePlan
					.PROJECT_NOT_COLLECTION:
				return getSpecificData(performancePlanVO, performancePlanData.getYear(),
						performancePlanData.getStatus(), performancePlanData.getBrandOrientation(),
						PerformancePlan.PROJECT_COLLECTION, performancePlanData.getVersion());
			default:
				return null;
		}
	}

	public PerformancePlanData getSpecificData(PerformancePlanVO performancePlanVO,
			Integer year, Integer operationType, Integer brandType, Integer clientType, Integer version) {
		for (PerformancePlanData performancePlanData : performancePlanVO.getData()) {
			if (Objects.equals(performancePlanData.getYear(), year)
					&& Objects.equals(performancePlanData.getStatus(), operationType)
					&& Objects.equals(performancePlanData.getBrandOrientation(), brandType)
					&& Objects.equals(performancePlanData.getProject(), clientType)
					&& Objects.equals(performancePlanData.getVersion(), version)) {
				return performancePlanData;
			}
		}
		return null;
	}

	/**
	 * 获取某一类型的数据, 如果latest = true, 则选取这类数据中最新的数据, 否则选择最早的数据
	 */
	public PerformancePlanData getSpecificData(PerformancePlanVO performancePlanVO,
			Integer year, Integer operationType, Integer brandType, Integer clientType, Boolean latest) {
		PerformancePlanVO forLatest = new PerformancePlanVO();
		BeanUtils.copyProperties(performancePlanVO, forLatest);
		if (latest) {
			performancePlanVO = filter.filterLatestData(Collections.singletonList(forLatest)).get(0);
		} else {
			performancePlanVO = filter.filterEarliestData(Collections.singletonList(forLatest)).get(0);
		}
		for (PerformancePlanData performancePlanData : performancePlanVO.getData()) {
			if (Objects.equals(performancePlanData.getYear(), year)
					&& Objects.equals(performancePlanData.getStatus(), operationType)
					&& Objects.equals(performancePlanData.getBrandOrientation(), brandType)
					&& Objects.equals(performancePlanData.getProject(), clientType)) {
				return performancePlanData;
			}
		}
		return null;
	}

	public Boolean checkIfThisDataIsLatest(PerformancePlanVO performancePlanVO,
			Integer year, Integer operationType, Integer brandType, Integer clientType, Integer version) {
		PerformancePlanVO forLatest = new PerformancePlanVO();
		BeanUtils.copyProperties(performancePlanVO, forLatest);
		performancePlanVO = filter.filterLatestData(Collections.singletonList(forLatest)).get(0);
		for (PerformancePlanData performancePlanData : performancePlanVO.getData()) {
			if (Objects.equals(performancePlanData.getYear(), year)
					&& Objects.equals(performancePlanData.getStatus(), operationType)
					&& Objects.equals(performancePlanData.getBrandOrientation(), brandType)
					&& Objects.equals(performancePlanData.getProject(), clientType)
					&& Objects.equals(performancePlanData.getVersion(), version)) {
				return true;
			}
		}
		return false;
	}


	/**
	 * 根据月份分类数据
	 */
	public Map<Integer, List<PerformanceReportDetail>> extractMonthData(
			List<PerformanceReportDetail> performanceReportDetailDOs) {
		Map<Integer, List<PerformanceReportDetail>> data = new HashMap<>(12);
		for (PerformanceReportDetail performanceReportDetailDO : performanceReportDetailDOs) {
			List<PerformanceReportDetail> performanceReportDetailDOList = data
					.get(performanceReportDetailDO.getMonth());
			if (CollectionUtils.isEmpty(performanceReportDetailDOList)) {
				performanceReportDetailDOList = new ArrayList<>(8);
				performanceReportDetailDOList.add(performanceReportDetailDO);
				data.put(performanceReportDetailDO.getMonth(), performanceReportDetailDOList);
			} else {
				performanceReportDetailDOList.add(performanceReportDetailDO);
			}
		}
		return data;
	}

	public PerformanceReportDetail getSpecificValue(
			Map<Integer, List<PerformanceReportDetail>> data,
			Integer year, Integer operationType, Integer brandType,
			Integer clientType, Integer version, Integer month) {
		// 先取出月度的数据
		List<PerformanceReportDetail> performanceReportDetailDOList = data.get(month);
		// 再根据数据的类型取出不同的数据
		for (PerformanceReportDetail performanceReportDetailDO : performanceReportDetailDOList) {
			// 判断各个数据是否一致, 如果一致则取出
			if (Objects.equals(year, performanceReportDetailDO.getYear())
					&& Objects.equals(operationType, performanceReportDetailDO.getStatus())
					&& Objects.equals(brandType, performanceReportDetailDO.getBrandType())
					&& Objects.equals(clientType, performanceReportDetailDO.getCustomerType())
					&& Objects.equals(version, performanceReportDetailDO.getVersion())) {
				return performanceReportDetailDO;
			}
		}
		return null;
	}

}
